#include "position.hpp"
#include <stdio.h>

namespace Trade {

static const price_t benchmark_max_win = 20;
static const price_t benchmark_max_win_lost = -10;
static price_t hop = 12;
// static price_t cost_hp = 3;
static price_t hp_force_stop_cost = 6;
static price_t hp_force_stop_loss = -50;

void
Position::print(const price_t hpx, const int64_t idx) const noexcept
{
  if (vol)
    printf(
      "\033[38;5;46m& Position &\033[0m \033[1;31m%d\033[0m avg: %.02lf "
      "Vol: %d | Float Rev: %.02lf %.02lf | maxw %.02lf maxl %.02lf | g%ld\n",
      d,
      avg_hpx,
      vol,
      float_hop_rvn,
      float_revenue,
      max_hop_win,
      max_hop_lost,
      idx);
}

void
Position::update_float_revenue(const price_t hpx) noexcept
{
  if (vol) {
    float_hop_rvn = (hpx - avg_hpx) * d;
    float_revenue = float_hop_rvn * vol * hop;

    if (float_hop_rvn > max_hop_win) {
      max_hop_win = float_hop_rvn;
      hp_max_win = hpx;
    }

    if (float_hop_rvn < max_hop_lost) {
      max_hop_lost = float_hop_rvn;
      max_lost_hp = hpx;
    }
  }
}

bool
Position::reached_max_win_loss(const price_t hpx) noexcept
{
  return ((max_hop_win > benchmark_max_win) &&
          (hpx - hp_max_win < benchmark_max_win_lost));
}

bool
Position::force_stop_win(const price_t hpx) noexcept
{
  if (vol < 1)
    return false;

  return ((max_hop_win > benchmark_max_win) &&
          (((hpx - avg_hpx) * d) >= hp_force_stop_cost));
}

bool
Position::force_stop_loss(const price_t hpx) noexcept
{
  if (vol < 1)
    return false;

  return (((hpx - avg_hpx) * d) < hp_force_stop_loss);
}

} // namespace Trade